#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QIcon>
#include <QKeyEvent>
#include <ctime>
#include <QFontDatabase>
#include <QString>
#include<QSoundEffect>

#include"config.h"
#include"fufu.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initWindow();

    QSoundEffect * startSound = new QSoundEffect(this);//创建对象
    startSound->setSource(QUrl::fromLocalFile(":/resource/bgm.wav"));//添加资源
    startSound->setLoopCount(QSoundEffect::Infinite);//设置循环次数int；  QSoundEffect::Infinite 枚举值 无限循环
    startSound->play();//软件启动自动播放
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initWindow(){
    setFixedSize(GAMEWIDTH,GAMEHEIGHT);
    setWindowTitle(GAMETITLE);
    setWindowIcon(QIcon(GAME_ICON));
    background.load(BACKGROUND_PATH);
    update();

    //导入字体
    int fontId=QFontDatabase::addApplicationFont(QStringLiteral(":/resource/FGO-Main-Font #0200159.ttf"));   //导入字体文件
    QStringList fontFamilies=QFontDatabase::applicationFontFamilies(fontId);
    QFont font;
    font.setFamily(fontFamilies[0]);
    ui->start->setFont(font);
    ui->introduce->setFont(font);
    ui->restart->setFont(font);
    ui->mainmenu->setFont(font);
    ui->score->setFont(font);
    ui->distance->setFont(font);
    ui->overscore->setFont(font);
    ui->overdistance->setFont(font);
    ui->end->setFont(font);


    ui->start->setGeometry(390,140,ui->start->width(),ui->start->height());      //大小
    ui->introduce->setGeometry(390,260,ui->introduce->width(),ui->introduce->height());
    ui->start->setFocusPolicy(Qt::NoFocus);
    ui->introduce->setFocusPolicy(Qt::NoFocus);
    ui->restart->setFocusPolicy(Qt::NoFocus);
    ui->mainmenu->setFocusPolicy(Qt::NoFocus);
    ui->score->hide();
    ui->distance->hide();
    ui->groupBox->hide();

    m_timer.setInterval(GAMERATE);                    //主定时器设置
    sprint_timer.setInterval(SPRINTTIME);         //冲刺定时器设置
    sprint_timer.setSingleShot(true);
    sprint_interval_timer.setInterval(SPRINTINTERVAL);
    sprint_interval_timer.setSingleShot(true);
    //物品生成
    add_Barrier_interval_timer.setInterval(ADDBARRIER_DURATION);
    add_stone_intervai_timer.setInterval(ADDSTONE_DURATION);
    add_stone_intervai_timer.setSingleShot(true);

    protected_timer.setInterval(PROTECTEDTIME);
    protected_timer.setSingleShot(true);

    fufu.y=FUFU_ONGROUND_Y;
    connect(&m_timer,&QTimer::timeout,[=](){
        updateposition();    //更新坐标
        collectdetection();  //碰撞检测
        ui->score->setText("Score: "+QString::number(score));   //更新分数
        ui->distance->setText("Distance: "+QString::number(Grounds.distance)+" m");
        update();          //刷新屏幕
    });
    connect(&add_Barrier_interval_timer,&QTimer::timeout,[=](){
        addBarrier();
    });

    score=0;
    Grounds.distance=0;
    ui->score->setText("Score: "+QString::number(score));
    ui->distance->setText("Distance: "+QString::number(Grounds.distance)+" m");
    sprint1=false;
    sprint2=false;


}//初始化完成

void MainWindow::paintEvent(QPaintEvent *event){Q_UNUSED(event);
    QPainter painter(this);
    painter.drawPixmap(0,0,background);    //绘制背景
    for(int i=0;i<9;i++){               //绘制地面
        painter.drawPixmap(Grounds.Grounds[i].groundpositionX,393,Grounds.Grounds[i].Ground);
    }
    painter.drawPixmap(fufu.x,fufu.y,fufu.getImg());
    for(auto& barr:Barriers)            //绘制障碍物
    {
        if(protected_timer.isActive()){
            painter.drawPixmap(barr->x,barr->y,barr->getImg(1));
        }
        else{
            painter.drawPixmap(barr->x,barr->y,barr->getImg(0));
        }
    }
}

void MainWindow::keyPressEvent(QKeyEvent *event){
    QKeyEvent *key=(QKeyEvent*) event;
    if(key->key()==Qt::Key_Space){                     //空格键跳跃
        fufu.jump();
    }
    if(key->key()==Qt::Key_Shift){                     //shift键冲刺
        sprint();
    }
}
void MainWindow::mousePressEvent(QMouseEvent *event){
    if(event->button()==Qt::LeftButton){    //左键跳跃
        fufu.jump();
    }
    if(event->button()==Qt::RightButton){   //右键冲刺
        sprint();
    }
}

void MainWindow::playgame(){
    score=0;
    Grounds.distance=0;
    ui->score->show();
    ui->distance->show();
    m_timer.start();            //启动计时器
    fufu.runtimer.start();
    add_Barrier_interval_timer.start();
}
void MainWindow::gameover(){
    m_timer.stop();
    sprint_timer.stop();
    sprint_interval_timer.stop();
    add_Barrier_interval_timer.stop();
    add_stone_intervai_timer.stop();
    fufu.runtimer.stop();
    protected_timer.stop();
    ui->groupBox->setGeometry(330,0,ui->groupBox->width(),ui->groupBox->height());
    ui->overscore->setText("Score: "+QString::number(score));
    ui->overdistance->setText("Distance: "+QString::number(Grounds.distance)+" m");
    ui->groupBox->show();
}

void MainWindow::updateposition(){           //更新对象坐标
    Grounds.Calculateposition();
    for(it=Barriers.begin();it!=Barriers.end();){
        if((*it)->isout()){
            it=Barriers.erase(it);
        }
        else{
            (*it)->updateposition();
            (*it)->updatebarrierpositionY();     //对象为咕哒子，则更新Y坐标；
            it++;
        }
    }
    fufu.updateY();
    if(this->sprint_timer.isActive()){
        Grounds.Calculateposition();
        Grounds.Calculateposition();
        for(auto& barr:Barriers)
        {
            barr->updateposition();
            barr->updateposition();
        }
    }
}

void MainWindow::collectdetection(){
    int i=0;
    for(it=Barriers.begin();it!=Barriers.end();){
        i=(*it)->collectdetection(fufu.fufurect);
        switch (i) {
        case 0:                       //无碰撞
            it++;
            break;
        case 1:{                      //障碍物
            it++;
            if(!protected_timer.isActive()&&!sprint_timer.isActive()){
                gameover();
            }
            break;
        }
        case 2:{                      //圣晶石
            protected_timer.start();
            it=Barriers.erase(it);
            score+=10;
            break;
        }
        case 3:{                      //qp
            it=Barriers.erase(it);
            score+=1;
            break;
        }
        default:
            break;
        }
    }
}

void MainWindow::sprint(){
    if(!sprint_interval_timer.isActive()){
        sprint1=false;
        sprint2=false;
    }
    if(sprint2||(sprint_timer.remainingTime()>90&&sprint_timer.isActive())){
        return;
    }
    if(!sprint1){
        sprint1=true;
        sprint_timer.start();
        sprint_interval_timer.start();
    }
    else if(!sprint2){
        sprint2=true;
        sprint_timer.start();
    }
}

void MainWindow::addBarrier(){                        //生成障碍物
    srand((unsigned int)time(NULL));
    i=rand()%4;
    switch (i) {
    case 0:
        Barriers.emplace_back(new Merlin);
        Barriers.emplace_back(new qp(1));
        break;
    case 1:
        Barriers.emplace_back(new gudazi);
        break;
    case 2:
        Barriers.emplace_back(new qp(2));
        break;
    case 3:
        if(add_stone_intervai_timer.isActive()){
            Barriers.emplace_back(new qp(2));
            return;
        }
        add_stone_intervai_timer.start();
        Barriers.emplace_back(new stone);
        break;
    default:
        break;
    }
}

void MainWindow::on_start_clicked()
{
    ui->start->hide();
    ui->introduce->hide();
    playgame();
}

void MainWindow::on_introduce_clicked()
{
    intro=new introduce;
    intro->setWindowFlags(Qt::WindowStaysOnTopHint);
    intro->show();
}


void MainWindow::on_restart_clicked()
{
    ui->groupBox->hide();
    Barriers.clear();
    fufu.y=FUFU_ONGROUND_Y;
    playgame();
}


void MainWindow::on_mainmenu_clicked()
{
    ui->groupBox->hide();
    ui->score->hide();
    ui->distance->hide();
    ui->start->show();
    ui->introduce->show();
    Barriers.clear();
    fufu.y=FUFU_ONGROUND_Y;
    update();
}

